package com.pfsoft.codehelper.service.impl;

import com.pfsoft.codehelper.common.query.StudentInfoQuery;
import com.pfsoft.codehelper.domain.StudentInfo;
import com.pfsoft.codehelper.repository.StudentInfoRepository;
import com.pfsoft.codehelper.service.IStudentInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Optional;
import org.springframework.data.domain.*;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.data.jpa.domain.Specification;
import org.springframework.util.StringUtils;
import java.util.List;
import java.util.ArrayList;
import java.lang.reflect.Field;
import com.pfsoft.codehelper.common.NotCondition;

/**
* @author pf
* @date 2020-06-11
*/
@Service
public class StudentInfoServiceImpl implements IStudentInfoService {

    @Autowired
    private StudentInfoRepository studentInfoRepository;


    @Override
    public StudentInfo findById(Long id) {
        Optional<StudentInfo> optional = studentInfoRepository.findById(id);
        if(optional.isPresent()){
            return  optional.get();
        }else{
            return null;
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public StudentInfo create(StudentInfo resources) {
        return studentInfoRepository.save(resources);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(StudentInfo resources) {
        Optional<StudentInfo> optional = studentInfoRepository.findById(resources.getId());
        if(optional.isPresent()){
            StudentInfo studentInfo = optional.get();
                    // 此处需自己修改
                    resources.setId(studentInfo.getId());
            studentInfoRepository.save(resources);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(Long id) {
        studentInfoRepository.deleteById(id);
    }

    @Override
    public Page<StudentInfo> getAll(StudentInfoQuery query, Pageable pageable) {
        return this.getDataList(query, pageable);
    }

    private Page<StudentInfo> getDataList(StudentInfoQuery query,Pageable pageable) {
    Specification<StudentInfo> querySpecifi = new Specification<StudentInfo>() {
        public Predicate toPredicate(Root<StudentInfo> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

            List<Predicate> predicates = new ArrayList<>();
                if (!StringUtils.isEmpty(query.getBeginDate())) {
                    //大于或等于传入时间
                    predicates.add(criteriaBuilder.greaterThanOrEqualTo(root.get("createTime").as(String.class), query.getBeginDate()));
                }
                if (!StringUtils.isEmpty(query.getEndDate())) {
                    //小于或等于传入时间
                    predicates.add(criteriaBuilder.lessThanOrEqualTo(root.get("createTime").as(String.class), query.getEndDate()));
                }
                if (query != null) {
                Class<? extends StudentInfoQuery> clazz = query.getClass();
                Field[] fields = clazz.getDeclaredFields();
                for (Field tmpField : fields) {
                    tmpField.setAccessible(true);
                    try {
                        NotCondition annotation = (NotCondition) tmpField.getDeclaredAnnotation(NotCondition.class);
                        if(tmpField.get(query)!=null && annotation==null)
                        {
                           String name = tmpField.getName();
                           predicates.add(criteriaBuilder.equal(root.get(name), tmpField.get(query)));
                        }
                        } catch (IllegalAccessException e) {
                             e.printStackTrace();
                        }
                    }
                }
                // and到一起的话所有条件就是且关系，or就是或关系
                return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));
            }
        };
        return  studentInfoRepository.findAll(querySpecifi,pageable);
    }
}